var __classPrivateFieldSet =
  (this && this.__classPrivateFieldSet) ||
  function (receiver, state, value, kind, f) {
    if (kind === 'm') throw new TypeError('Private method is not writable');
    if (kind === 'a' && !f) throw new TypeError('Private accessor was defined without a setter');
    if (typeof state === 'function' ? receiver !== state || !f : !state.has(receiver))
      throw new TypeError('Cannot write private member to an object whose class did not declare it');
    return kind === 'a' ? f.call(receiver, value) : f ? (f.value = value) : state.set(receiver, value), value;
  };
var __classPrivateFieldGet =
  (this && this.__classPrivateFieldGet) ||
  function (receiver, state, kind, f) {
    if (kind === 'a' && !f) throw new TypeError('Private accessor was defined without a getter');
    if (typeof state === 'function' ? receiver !== state || !f : !state.has(receiver))
      throw new TypeError('Cannot read private member from an object whose class did not declare it');
    return kind === 'm' ? f : kind === 'a' ? f.call(receiver) : f ? f.value : state.get(receiver);
  };
var _MyPromise_instances,
  _MyPromise_status,
  _MyPromise_rea_res,
  _MyPromise_handlers,
  _MyPromise_onSettled,
  _MyPromise_flush,
  _MyPromise_getNextPromise;
const microQueen = [];
class MyPromise {
  constructor(fn) {
    _MyPromise_instances.add(this);
    _MyPromise_status.set(this, 'pending');
    _MyPromise_rea_res.set(this, undefined);
    _MyPromise_handlers.set(this, []);
    const resolve = (res) => {
      __classPrivateFieldSet(this, _MyPromise_status, 'fulfilled', 'f');
      __classPrivateFieldSet(this, _MyPromise_rea_res, res, 'f');
      __classPrivateFieldGet(this, _MyPromise_instances, 'm', _MyPromise_flush).call(this);
    };
    const reject = (rea) => {
      __classPrivateFieldSet(this, _MyPromise_status, 'rejected', 'f');
      __classPrivateFieldSet(this, _MyPromise_rea_res, rea, 'f');
      __classPrivateFieldGet(this, _MyPromise_instances, 'm', _MyPromise_flush).call(this);
    };
    try {
      // 为什么要首先在构造其中产生一个特殊的handler？
      // 考虑作为最后一个promise，没有处理异常的情况 ，需要抛出异常，这在onSettled中已经实现。
      // 我们要做的只是，添加一个没有nextReject的handler，即这里的特殊handler
      // 因为：没有handler flush循环将不会执行任何代码
      //
      // 当然如果不是最后一个，那么必然通过then、catch、finally方法中的一个，产生了一个正常的handler。 onSettled会将异常的处理转移过去
      // 注意flush，当同步代码执行完后，只有一个handler时，那必然是这个特殊的handler；如果有多个，那一定要移除这个handler，因为异常转移到下一个环节了。
      __classPrivateFieldGet(this, _MyPromise_handlers, 'f').push({ handled: false });
      fn(resolve, reject);
    } catch (e) {
      __classPrivateFieldSet(this, _MyPromise_status, 'rejected', 'f');
      __classPrivateFieldSet(this, _MyPromise_rea_res, e, 'f');
      __classPrivateFieldGet(this, _MyPromise_instances, 'm', _MyPromise_flush).call(this);
    }
  }
  static resolve(data) {
    return new MyPromise((res) => {
      res(data);
    });
  }
  static reject(data) {
    return new MyPromise((_, rej) => {
      rej(data);
    });
  }
  then(fn1, fn2) {
    return __classPrivateFieldGet(this, _MyPromise_instances, 'm', _MyPromise_getNextPromise).call(this, {
      thenFn: fn1,
      catchFn: fn2,
    });
  }
  catch(fn) {
    return __classPrivateFieldGet(this, _MyPromise_instances, 'm', _MyPromise_getNextPromise).call(this, {
      catchFn: fn,
    });
  }
  finally(fn) {
    return __classPrivateFieldGet(this, _MyPromise_instances, 'm', _MyPromise_getNextPromise).call(this, {
      finallyFn: fn,
    });
  }
}
(_MyPromise_status = new WeakMap()),
  (_MyPromise_rea_res = new WeakMap()),
  (_MyPromise_handlers = new WeakMap()),
  (_MyPromise_instances = new WeakSet()),
  (_MyPromise_onSettled = function _MyPromise_onSettled(handler) {
    if (__classPrivateFieldGet(this, _MyPromise_status, 'f') === 'pending') {
      return;
    }
    let nextState = __classPrivateFieldGet(this, _MyPromise_status, 'f');
    let nextRes_Rea = __classPrivateFieldGet(this, _MyPromise_rea_res, 'f');
    /**
     * 关键点1：函数执行
     *  thenFn finallyFn 只会存在一个，或都不存在;
     *  catchFn finallyFn 只会存在一个，或都不存在 ;
     *  catchFn thenFn 可能同时存在，但只会执行其中一个;
     *  三个方法至少存在一个，但考虑到status情况，三个方法可能都不执行
     * 关键点2：下一链的状态
     *  基于关键点1，next的status和res_rea默认继承当前的，
     *  如果执行了thenFn或catchFn，则成功返回一个值或产生的异常
     *  无论那种情况，都将作为新的next的res_rea，成功返回 新的status为fulfilled，产生异常 新的status是rejected
     * 关键点3：处理下一链
     *  关键点2中忽略了返回Promise的情况，所以最后判断。
     *  如果是这种情况，直接将nextResolve和nextReject作为该返回promise的next值即可。一切交给递归。
     *  当然如果不是promise，那么应该立即执行两者中的一个。
     * 关键点4：异常
     *  异常存在于每次可能的执行（构造器，then，catch，finally)，都要做异常捕获置为rejected
     *  此时必须调用catch，否则最后都要真正的throw这个异常
     * 关键点5：异常必须catch或对外抛出
     *  一个promise存在异常（rejected），由它延伸出的每条调用链都必须处理，否则外界将收到异常
     *  且至少有一个链处理吧！
     */
    try {
      if (__classPrivateFieldGet(this, _MyPromise_status, 'f') === 'fulfilled' && handler.thenFn) {
        nextRes_Rea = handler.thenFn(__classPrivateFieldGet(this, _MyPromise_rea_res, 'f'));
        nextState = 'fulfilled';
      }
      if (__classPrivateFieldGet(this, _MyPromise_status, 'f') === 'rejected' && handler.catchFn) {
        nextRes_Rea = handler.catchFn(__classPrivateFieldGet(this, _MyPromise_rea_res, 'f'));
        nextState = 'fulfilled';
      }
      if (handler.finallyFn) {
        handler.finallyFn();
      }
    } catch (e) {
      nextRes_Rea = e;
      nextState = 'rejected';
    }
    // -----------------------------------------------
    // 处理下一链（异常不会是promise吧！可能是，所以要加判断）
    // promise情况：移花接木，后续链接到新的promise上（接到nextRes_Rea上）
    // 剩余：异常情况 或 普通值的fulfilled.
    // 普通的fulfilled，直接处理；异常情况，要么成功转移到下一个，要么抛出
    if (nextRes_Rea instanceof MyPromise && nextState === 'fulfilled') {
      const nextHandler = {
        nextReject: handler.nextReject,
        nextResolve: handler.nextResolve,
        handled: false,
      };
      __classPrivateFieldGet(nextRes_Rea, _MyPromise_handlers, 'f').push(nextHandler);
      if (__classPrivateFieldGet(nextRes_Rea, _MyPromise_status, 'f') !== 'pending') {
        __classPrivateFieldGet(nextRes_Rea, _MyPromise_instances, 'm', _MyPromise_flush).call(nextRes_Rea);
      }
      return;
    }
    if (nextState === 'fulfilled') {
      handler.nextResolve?.(nextRes_Rea);
      return;
    }
    if (handler.nextReject) {
      handler.nextReject(nextRes_Rea);
    } else {
      throw nextRes_Rea;
    }
  }),
  (_MyPromise_flush = function _MyPromise_flush() {
    microQueen.push(() => {
      if (__classPrivateFieldGet(this, _MyPromise_handlers, 'f').length > 1) {
        __classPrivateFieldGet(this, _MyPromise_handlers, 'f').shift();
      }
      while (__classPrivateFieldGet(this, _MyPromise_handlers, 'f').length)
        microQueen.push(
          __classPrivateFieldGet(this, _MyPromise_instances, 'm', _MyPromise_onSettled).bind(
            this,
            __classPrivateFieldGet(this, _MyPromise_handlers, 'f').shift()
          )
        );
    });
  }),
  (_MyPromise_getNextPromise = function _MyPromise_getNextPromise(h) {
    let pro = new MyPromise((resolve, reject) => {
      const handler = {
        ...h,
        nextReject: reject,
        nextResolve: resolve,
        handled: false,
      };
      __classPrivateFieldGet(this, _MyPromise_handlers, 'f').push(handler);
      if (__classPrivateFieldGet(this, _MyPromise_status, 'f') !== 'pending') {
        __classPrivateFieldGet(this, _MyPromise_instances, 'm', _MyPromise_flush).call(this);
      }
    });
    return pro;
  });
const timerId = setInterval(() => {
  let fn = microQueen.shift();
  if (fn) {
    fn();
  } else {
    clearInterval(timerId);
  }
}, 10);
let w = globalThis || { MyPromise: Function };
w.MyPromise = MyPromise;
